import { useEffect, useRef } from 'react';
import { useLocation, useNavigate } from 'react-router-dom';
import { requiresAuthentication, getRouteMetadata, ROUTE_PATHS } from './routes';

/**
 * 路由守卫配置
 */
export interface IRouteGuardConfig {
  /** 是否启用认证检查 */
  enableAuth: boolean;
  /** 默认重定向路径 */
  defaultRedirect: string;
  /** 认证失败重定向路径 */
  authFailRedirect: string;
}

/**
 * 默认路由守卫配置
 */
export const defaultGuardConfig: IRouteGuardConfig = {
  enableAuth: false, // 当前版本不需要认证
  defaultRedirect: ROUTE_PATHS.HOME,
  authFailRedirect: ROUTE_PATHS.HOME
};

/**
 * 认证状态接口
 */
export interface IAuthState {
  /** 是否已认证 */
  isAuthenticated: boolean;
  /** 用户信息 */
  user?: {
    id: string;
    name: string;
    role: string;
  };
  /** 权限列表 */
  permissions?: string[];
}

/**
 * 模拟认证状态（当前版本始终返回已认证）
 * @returns 认证状态
 */
export const useAuthState = (): IAuthState => {
  // 在实际应用中，这里应该从状态管理或API获取认证状态
  return {
    isAuthenticated: true, // 当前版本不需要认证，始终返回true
    user: {
      id: 'local_user',
      name: '本地用户',
      role: 'admin'
    },
    permissions: ['*'] // 拥有所有权限
  };
};

/**
 * 路由权限检查
 * @param path 路由路径
 * @param authState 认证状态
 * @returns 是否有权限访问
 */
export const checkRoutePermission = (
  path: string,
  authState: IAuthState
): boolean => {
  // 如果未启用认证，直接返回true
  if (!defaultGuardConfig.enableAuth) {
    return true;
  }

  // 检查是否需要认证
  if (requiresAuthentication(path)) {
    return authState.isAuthenticated;
  }

  return true;
};

/**
 * 路由守卫Hook
 * @description 在组件中使用此Hook来实现路由守卫功能
 */
export const useRouteGuard = (config: Partial<IRouteGuardConfig> = {}) => {
  const location = useLocation();
  const navigate = useNavigate();
  const authState = useAuthState();
  
  const guardConfig = { ...defaultGuardConfig, ...config };
  
  // 使用ref来避免不必要的重复执行
  const lastPathRef = useRef<string>('');
  const lastTitleRef = useRef<string>('');

  useEffect(() => {
    const currentPath = location.pathname;
    
    // 如果路径没有变化，跳过处理
    if (lastPathRef.current === currentPath) {
      return;
    }
    lastPathRef.current = currentPath;
    
    // 检查路由权限
    const hasPermission = checkRoutePermission(currentPath, authState);
    
    if (!hasPermission) {
      // 如果没有权限，重定向到认证失败页面
      console.warn(`访问被拒绝: ${currentPath}`);
      navigate(guardConfig.authFailRedirect, { replace: true });
      return;
    }

    // 更新页面标题（只在标题变化时更新）
    const routeMeta = getRouteMetadata(currentPath);
    if (routeMeta?.title) {
      const newTitle = `${routeMeta.title} - 课程表管理系统`;
      if (lastTitleRef.current !== newTitle) {
        document.title = newTitle;
        lastTitleRef.current = newTitle;
      }
    }
  }, [location.pathname, authState.isAuthenticated, navigate, guardConfig.authFailRedirect]);

  return {
    authState,
    hasPermission: checkRoutePermission(location.pathname, authState),
    currentRoute: getRouteMetadata(location.pathname)
  };
};

/**
 * 导航守卫Hook
 * @description 用于在导航前进行权限检查
 */
export const useNavigationGuard = () => {
  const navigate = useNavigate();
  const authState = useAuthState();

  /**
   * 安全导航函数
   * @param path 目标路径
   * @param options 导航选项
   */
  const safeNavigate = (
    path: string,
    options?: { replace?: boolean; state?: any }
  ) => {
    // 检查目标路由权限
    const hasPermission = checkRoutePermission(path, authState);
    
    if (!hasPermission) {
      console.warn(`导航被拒绝: ${path}`);
      navigate(defaultGuardConfig.authFailRedirect, { replace: true });
      return false;
    }

    navigate(path, options);
    return true;
  };

  return {
    safeNavigate,
    checkPermission: (path: string) => checkRoutePermission(path, authState)
  };
};

/**
 * 路由错误处理
 */
export class RouteError extends Error {
  constructor(
    message: string,
    public code: string,
    public path: string
  ) {
    super(message);
    this.name = 'RouteError';
  }
}

/**
 * 路由错误处理器
 * @param error 错误对象
 * @param path 出错的路径
 */
export const handleRouteError = (error: Error, path: string) => {
  console.error('路由错误:', {
    message: error.message,
    path,
    stack: error.stack
  });

  // 在实际应用中，这里可以上报错误到监控系统
  // 或者显示用户友好的错误提示
};

/**
 * 路由加载状态管理
 */
export const useRouteLoading = () => {
  const location = useLocation();

  // 在实际应用中，可以根据路由变化显示加载状态
  // 这里提供基础的实现
  return {
    isLoading: false, // 当前版本不需要复杂的加载状态
    currentPath: location.pathname
  };
};